<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>案例</title>
</head>

<body>
    <script>
        // 数组方法的封装

        // map的封装
        Array.prototype.myMap = function (cb) {
            let result = []

            for (let i = 0; i < this.length; i++) {
                result[i] = cb(this[i], i, this)
            }

            return result
        }
        // 测试
        console.log([1, 2, 3].myMap(i => i ** 2)) // [1,4,9]

        // filter方法的封装
        Array.prototype.myFilter = function (cb) {
            let result = []

            for (let i = 0; i < this.length; i++) {
                if (cb(this[i], i, this)) {
                    result.push(this[i])
                }
            }

            return result
        }

        console.log([1, 2, 3].myFilter(item => item > 1)) // [2,3]

        // every方法的封装
        Array.prototype.myEvery = function (cb) {
            let count = 0
            for (let i = 0; i < this.length; i++) {
                if (cb(this[i], i, this)) {
                    count++
                }
            }

            if (count === this.length) {
                return true
            }

            return false
        }

        console.log([1, 2, 3].myEvery(item => item > 0)) // true

        // some方法的封装
        Array.prototype.mySome = function (cb) {
            let count = 0
            for (let i = 0; i < this.length; i++) {
                if (cb(this[i], i, this)) {
                    count++
                }
            }
            if (count >= 1) {
                return true
            }
            return false
        }

        console.log([1, 2, 3].mySome(item => item > 2)) // true

        // forEach方法封装 
        Array.prototype.myForEach = function (cb) {
            for (let i = 0; i < this.length; i++) {
                cb(this[i], i, this)
            }
        }



        ;
        [1, 2, 3].myForEach(item => console.log(item + 1)) // 2 3 4

        // 给字符串强行添加forEach方法
        String.prototype.forEach = function (cb) {
            for (let i = 0; i < this.length; i++) {
                cb(this[i], i, this)
            }
        }
        'asdf'.forEach(i => console.log(i)) // a s d f

        // 给字符串添加reverse方法
        String.prototype.reverse = function () {
            return this.split('').reverse().join('')
        }
        console.log('asdf'.reverse()) // fdsa

        // 利用call 实现 bind方法
        Function.prototype.myBind = function (obj, ...args1) {
            // let that = this
            // return function (...args2) {
            //     return that.call(obj, ...args1, ...args2)
            // }

            return (...args2) => this.call(obj, ...args1, ...args2)
        }

        function foo(a, b, c) {
            console.log(this.name, a, b, c);
        }

        let f = foo.myBind({
            name: '大卫'
        }, 1, 2)
        f(3) // 大卫 1 2 3
    </script>
</body>

</html>